package com.itcm.tcpdemo.model;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Data;

import java.io.IOException;

@Data
public class Packet {
    private static final ObjectMapper objectMapper = new ObjectMapper();

    private byte protocolVersion;
    private byte messageType;
    private byte flags;
    private byte reserved;
    private int dataLength;
    private Object body; // 包体内容可以是任意类型
    private ByteBuf bodyBuffer; // 临时保存包体的 ByteBuf

    public Packet(byte protocolVersion, byte messageType, byte flags, int dataLength) {
        this.protocolVersion = protocolVersion;
        this.messageType = messageType;
        this.flags = flags;
        this.reserved = 0x00; // 默认值
        this.dataLength = dataLength;
    }

    // 从 ByteBuf 构建 Packet（用于接收）
    public static Packet fromByteBuf(ByteBuf in) throws IOException {
        byte protocolVersion = in.readByte();
        byte messageType = in.readByte();
        byte flags = in.readByte();
        byte reserved = in.readByte();
        int dataLength = in.readInt();

        ByteBuf bodyBuffer = in.readBytes(dataLength);

        Packet packet = new Packet(protocolVersion, messageType, flags, dataLength);
        packet.setBodyBuffer(bodyBuffer.retain()); // 保留引用以避免被释放

        return packet;
    }

    // 将 Packet 转换为字节数组（用于发送）
    public byte[] toBytes() throws IOException {
        byte[] bodyBytes = body == null ? new byte[0] : objectMapper.writeValueAsBytes(body);
        int totalLength = 8 + bodyBytes.length;
        ByteBuf buffer = Unpooled.buffer(totalLength);
        buffer.writeByte(protocolVersion);
        buffer.writeByte(messageType);
        buffer.writeByte(flags);
        buffer.writeByte(reserved);
        buffer.writeInt(bodyBytes.length);
        buffer.writeBytes(bodyBytes);

        byte[] result = buffer.array();
        buffer.release();
        return result;
    }

    @Override
    public String toString() {
        return "Packet{" +
                "protocolVersion=" + (int) protocolVersion +
                ", messageType=" + (int) messageType +
                ", flags=" + (int) flags +
                ", reserved=" + (int) reserved +
                ", dataLength=" + dataLength +
                ", body=" + body +
                '}';
    }
}